package org.linlinjava.litemall.db.service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Resource;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
import org.linlinjava.litemall.db.dao.LitemallOrderMapper;
import org.linlinjava.litemall.db.dao.LitemallRechargeConsumptionMapper;
import org.linlinjava.litemall.db.dao.LitemallUserMapper;
import org.linlinjava.litemall.db.dao.UserMapper;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.util.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
 

/**
 * litemall用户服务
 *
 * @author yliyun
 * @date 2022/09/19
 */
@Service
public class LitemallUserService extends MPJBaseServiceImpl<LitemallUserMapper,LitemallUser> {
    /**
     * litemall用户映射器
     */
    @Resource
    private LitemallUserMapper litemallUserMapper;
    /**
     * 用户映射器
     */
    @Resource
    private UserMapper userMapper;


    /**
     * 身份证名字
     */
    private LitemallUser.Column[] ID_NAME = {LitemallUser.Column.username, LitemallUser.Column.id};


    public Map<Integer,LitemallUser> getUserMap(Collection<Integer> ids){
        if(CollUtil.isEmpty(ids)) return CollUtil.newHashMap();
        return CollectionUtils.convertMap(this.listByIds(ids),LitemallUser::getId);
    }

    /**
     * 发现通过id
     *
     * @param userId 用户id
     * @return {@link LitemallUser}
     */
    public LitemallUser findById(Integer userId) {
        return litemallUserMapper.selectByPrimaryKey(userId);
    }

    /**
     * 按主键删除用户
     *
     * @param id id
     * @return {@link Integer}
     */
    @Transactional
    public Integer deleteByPrimaryKey(Integer id){
        return litemallUserMapper.deleteByPrimaryKey(id);
    }



    /**
     * 找到用户签证官通过id
     *
     * @param userId 用户id
     * @return {@link UserVo}
     */
    public UserVo findUserVoById(Integer userId) {
        LitemallUser user = findById(userId);
        UserVo userVo = new UserVo();
        userVo.setNickname(user.getNickname());
        userVo.setAvatar(user.getAvatar());
        return userVo;
    }

    /**
     * 查询oid
     *
     * @param openId 开放id
     * @return {@link LitemallUser}
     */
    public LitemallUser queryByOid(String openId) {
        LitemallUserExample example = new LitemallUserExample();
        example.or().andWeixinOpenidEqualTo(openId).andDeletedEqualTo(false);
        return litemallUserMapper.selectOneByExample(example);
    }

    /**
     * 添加
     *
     * @param user 用户
     */
    public void add(LitemallUser user) {
        user.setAddTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        litemallUserMapper.insertSelective(user);
    }

    /**
     * 更新通过id
     *
     * @param user 用户
     * @return int
     */
    public int updateById2(LitemallUser user) {
        user.setUpdateTime(LocalDateTime.now());
        return litemallUserMapper.updateByPrimaryKeySelective(user);
    }

    /**
     * 查询选择性
     *
     * @param username 用户名
     * @param mobile   移动
     * @param page     页面
     * @param size     大小
     * @param sort     排序
     * @param order    订单
     * @return {@link List}<{@link LitemallUser}>
     */
    public List<LitemallUser> querySelective(String username, String mobile, Integer page, Integer size, String sort, String order) {
        LitemallUserExample example = new LitemallUserExample();
        LitemallUserExample.Criteria criteria = example.createCriteria();

        if (!StringUtils.isEmpty(username)) {
            criteria.andUsernameLike("%" + username + "%");
            example.or().andMobileLike("%" + username + "%").andInnerAccountEqualTo(false).
            example().or().andNicknameLike("%" + username + "%").andInnerAccountEqualTo(false).
            example().or().andEmailLike("%" + username + "%");
        }
        if (!StringUtils.isEmpty(mobile)) {
            criteria.andMobileLike("%" + mobile + "%");
        }
        criteria.andInnerAccountEqualTo(false);
        criteria.andDeletedEqualTo(false);
        if (!StringUtils.isEmpty(sort) && !StringUtils.isEmpty(order)) {
            example.setOrderByClause(sort + " " + order);
        }

        //PageHelper.startPage(page, size);
        return litemallUserMapper.selectByExample(example);
    }


    /**
     * 数
     *
     * @return int
     */
    public long count() {
        LitemallUserExample example = new LitemallUserExample();

        example.or().andDeletedEqualTo(false).andInnerAccountEqualTo(false);

        return litemallUserMapper.countByExample(example);
    }

    /**
     * 数没有内在
     *
     * @return int
     */
    public int countNoInner() {
        LitemallUserExample example = new LitemallUserExample();
        example.or().andDeletedEqualTo(false).andInnerAccountEqualTo(false);

        return (int) litemallUserMapper.countByExample(example);
    }


    /**
     * 查询手机
     *
     * @param mobile 移动
     * @return {@link List}<{@link LitemallUser}>
     */
    public List<LitemallUser> queryByMobile(String mobile) {
        LitemallUserExample example = new LitemallUserExample();
        example.or().andMobileEqualTo(mobile).andDeletedEqualTo(false);
        return litemallUserMapper.selectByExample(example);
    }


    /**
     * 通过电子邮件查询
     *
     * @param email 电子邮件
     * @return {@link List}<{@link LitemallUser}>
     */
    public List<LitemallUser> queryByEmail(String email) {
        LitemallUserExample example = new LitemallUserExample();
        example.or().andEmailEqualTo(email).andDeletedEqualTo(false).andInnerAccountEqualTo(false);
        return litemallUserMapper.selectByExample(example);
    }


    /**
     * 查询手机或电子邮件
     *
     * @param contact 联系
     * @return {@link LitemallUser}
     */
    public LitemallUser queryMobileOrEmail(String contact) {
        LitemallUserExample example = new LitemallUserExample();
        example.or().andEmailEqualTo(contact).andInnerAccountEqualTo(false).andDeletedEqualTo(false);
        example.or().andMobileEqualTo(contact).andInnerAccountEqualTo(false).andDeletedEqualTo(false);
        return litemallUserMapper.selectOneByExample(example);
    }


    /**
     * 删除通过id
     *
     * @param id id
     */
    public void deleteById(Integer id) {
        litemallUserMapper.logicalDeleteByPrimaryKey(id);
    }

    /**
     * 总计
     *
     * @return long
     */
    public long total() {
        LitemallUserExample example = new LitemallUserExample();
        example.or().andDeletedEqualTo(false);
        return litemallUserMapper.countByExample(example);
    }

    /**
     * 查询添加用户统计
     *
     * @param map 地图
     * @return {@link List}<{@link Map}<{@link String}, {@link Object}>>
     */
    public List<Map<String, Object>>  queryAddUserStatistics(Map<String, Object> map){
        return userMapper.queryUserStatistics(map);
    }

    /**
     * 查询所有
     *
     * @return {@link List}<{@link LitemallUser}>
     */
    public List<LitemallUser> queryAll() {
        LitemallUserExample example = new LitemallUserExample();
        example.or().andDeletedEqualTo(false);
        return litemallUserMapper.selectByExample(example);
    }

    /**
     * 查询所有应用程序
     *
     * @return {@link List}<{@link LitemallUser}>
     */
    public List<LitemallUser> queryAllApp() {
        LitemallUserExample example = new LitemallUserExample();
        example.or().andDeletedEqualTo(false).andInnerAccountEqualTo(false);
        return litemallUserMapper.selectByExample(example);
    }

    /**
     * 查询所有没有内在
     *
     * @return {@link List}<{@link LitemallUser}>
     */
    public List<LitemallUser> queryAllNoInner() {
        LitemallUserExample example = new LitemallUserExample();
        example.or().andDeletedEqualTo(false).andInnerAccountEqualTo(false);
        return litemallUserMapper.selectByExample(example);
    }



    /**
     * 查询用户级别
     *
     * @param integers 整数
     * @return {@link List}<{@link LitemallUser}>
     */
    public List<LitemallUser> queryByUserLevels(List<Byte> integers) {
        LitemallUserExample example = new LitemallUserExample();
        example.or().andUserLevelIn(integers).andDeletedEqualTo(false);
        return litemallUserMapper.selectByExample(example);
    }

    /**
     * 更新了乐观锁
     *
     * @param update     更新
     * @param updateTime 更新时间
     * @return int
     */
    public int updateWithOptimisticLocker(LitemallUser update, LocalDateTime updateTime) {
        LitemallUserExample example = new LitemallUserExample();
        example.or().andIdEqualTo(update.getId())
                .andAvailableAmountEqualTo(update.getAvailableAmount())
                .andDeletedEqualTo(false);
        return litemallUserMapper.updateByExampleSelective(update,example);
    }

    /**
     * 找到名字
     *
     * @param userName 用户名
     * @return {@link List}<{@link LitemallUser}>
     */
    public List<LitemallUser> findByName(String userName) {
        LitemallUserExample example = new LitemallUserExample();
        example.or().andUsernameLike("%"+userName+"%").andDeletedEqualTo(false);
        return litemallUserMapper.selectByExample(example);
    }


    /**
     * 删除用户名
     *
     * @param username 用户名
     */
    public void deleteByUserName(String username) {
        LitemallUserExample example = new LitemallUserExample();
        example.or().andUsernameEqualTo(username).andInnerAccountEqualTo(true).andDeletedEqualTo(false);
        litemallUserMapper.logicalDeleteByExample(example);
    }

    /**
     * 发现由管理
     *
     * @param username     用户名
     * @param innerAccount 内部账户
     * @return {@link LitemallUser}
     */
    public LitemallUser findByAdmin(String username, boolean innerAccount) {
        LitemallUserExample example = new LitemallUserExample();
        example.or().andUsernameEqualTo(username).andInnerAccountEqualTo(innerAccount).andDeletedEqualTo(false);
        return litemallUserMapper.selectOneByExample(example);
    }


    /**
     * 查询会话密钥
     *
     * @param sessionKey 会话密钥
     * @return {@link List}<{@link LitemallUser}>
     */
    public List<LitemallUser> queryBySessionKey(String sessionKey) {
        LitemallUserExample example = new LitemallUserExample();
        example.or().andSessionKeyEqualTo(sessionKey).andDeletedEqualTo(false);
        return litemallUserMapper.selectByExample(example);
    }

    /**
     * 查询条件
     *
     * @param condition 条件
     * @return {@link List}<{@link LitemallUser}>
     */
    public List<LitemallUser> queryByCondition(String condition) {
        return userMapper.queryByCondition(condition);
    }

    /**
     * 按关键字查询
     *
     * @param keyword 关键字
     * @return {@link List}<{@link LitemallUser}>
     */
    public List<LitemallUser> queryByKeyword(String keyword) {
        LitemallUserExample example = new LitemallUserExample();
        if(keyword != null){
            example.or().andUsernameLike("%"+keyword+"%").andDeletedEqualTo(false).andInnerAccountEqualTo(false);
            example.or().andMobileLike("%"+keyword+"%").andDeletedEqualTo(false).andInnerAccountEqualTo(false);
            example.or().andEmailLike("%"+keyword+"%").andDeletedEqualTo(false).andInnerAccountEqualTo(false);
        }else{
            example.or().andInnerAccountEqualTo(false);
        }
        return litemallUserMapper.selectByExampleSelective(example, ID_NAME);
    }

    /**
     * 查询用户级别会员id
     *
     * @param levelMemberId 级会员id
     * @return {@link List}<{@link LitemallUser}>
     */
    public List<LitemallUser> queryUserByLevelMemberId(Integer levelMemberId){
        LitemallUserExample example = new LitemallUserExample();
        example.or().andUserLevelEqualTo(levelMemberId.byteValue()).andDeletedEqualTo(false);
        return litemallUserMapper.selectByExample(example);
    }

    /**
     * 查询用户通过邀请代码
     *
     * @param invitedCode 邀请码
     * @return {@link List}<{@link LitemallUser}>
     */
    public List<LitemallUser> queryUserByInvitedCode(String invitedCode){
        LitemallUserExample example = new LitemallUserExample();
        if(invitedCode != null){
            example.or().andInvitedCodeEqualTo(invitedCode);
        }else{
            example.or();
        }

        return litemallUserMapper.selectByExample(example);
    }



    /**
     * char和num
     *
     * @return {@link String}
     */
    public String getCharAndNum(){
        return getChar(4) + getNumr(4);
    }

    /**
     * 得到numr
     *
     * @param length 长度
     * @return {@link String}
     */
    public static String getNumr(int length) {

        Random random = new Random();

        StringBuffer valSb = new StringBuffer();

        String charStr = "0123456789";

        int charLength = charStr.length();



        for (int i = 0; i < length; i++) {

            int index = random.nextInt(charLength);

            valSb.append(charStr.charAt(index));

        }

        return valSb.toString();

    }


    /**
     * 把字符
     *
     * @param length 长度
     * @return {@link String}
     */
    public static String getChar(int length) {

        Random random = new Random();

        StringBuffer valSb = new StringBuffer();

        String charStr = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

        int charLength = charStr.length();



        for (int i = 0; i < length; i++) {

            int index = random.nextInt(charLength);

            valSb.append(charStr.charAt(index));

        }

        return valSb.toString();

    }


    public int setAvailableAmount(LitemallUser litemallUser){
        return litemallUserMapper.updateById(litemallUser);
    }


    /**
     * 删除会员，非物理删除
     * 冻结
     * @param userId
     * @return
     */
    public Boolean userRemove(Integer userId){
        LitemallUser user = findById(userId);
        user.setStatus((byte) 3);
        user.setUpdateTime(LocalDateTime.now());
        return updateById(user);
    }



}
